from subprocess import *
from enum import Enum
import re
import sys
import os
import time
from sgfmill import sgf
sys.path.append('../')
from goEnv import *
from goJudge import *
from utilities import *

gnugo=["gnugo","--mode", "gtp","--level","5","--chinese-rules"]
fuego=["fuego"]
pachi=[".\Pachi\pachi"]

cols='ABCDEFGHJKLMNOPQRST'


class move_info():
    def __init__(self,color,point):
        if color==1:
            self.colour='b'
        elif color==-1:
            self.colour='w'
        else:
            self.colour=None
        self.move=point


class ai_vs_ai():
    def __init__(self,ai_b=None,ai_w=None):
        global gnugo,fuego,pachi
        if ai_b == 'gnugo':
            self.ai_b=gnugo
        elif ai_b == 'fugeo':
            self.ai_b=fuego
        elif ai_b == 'pachi':
            self.ai_b=pachi
        else:
            self.ai_b=ai_b
        if ai_w == 'gnugo':
            self.ai_w=gnugo
        elif ai_w == 'fugeo':
            self.ai_w=fuego
        elif ai_w == 'pachi':
            self.ai_w=pachi
        else:
            self.ai_w=ai_w
        self.pipe_to_ai_b=Popen(self.ai_b,shell=True,stdin=PIPE, stdout=PIPE,bufsize=0, universal_newlines=True)
        self.pipe_to_ai_w=Popen(self.ai_w,shell=True,stdin=PIPE, stdout=PIPE,bufsize=0, universal_newlines=True)
        self.play_now=1 #1表示黑棋下，-1表示白棋下，0表示弃手
        self.is_pass=False
        self.who_wins=None

    def cmd_to_op(self,color,command):
        if color==1:
            self.pipe_to_ai_b.stdin.write(command+'\n')
        elif color==-1:
            self.pipe_to_ai_w.stdin.write(command+'\n')


    def get_resp(self,color):
        succeed=False
        resp=""
        while not succeed:
            if color==1:
                line = self.pipe_to_ai_b.stdout.readline()
            elif color==-1:
                line = self.pipe_to_ai_w.stdout.readline()
            else:
                line = '='
            if line[0]=='=':
                succeed=True
                line=line.strip()
                resp=re.sub('^= ?','',line)
        return resp

    def get_move(self,color):
        if color == 1:
            player="B"
        else:
            player="W"
        command="genmove "+player
        return self.cmd_and_resp(color,command)

    def inform(self,color,info):
        if color == -1:
            player="B"
        else:
            player="W"
        command="play "+player+" "+info
        return self.cmd_and_resp(color,command)

    def gtp_position_to_coords(self,gtp_position,mode=1):   #mode=1，原点是(0,0)，mode=2，原点是(1,1)
        col_str,row_str=gtp_position[0],gtp_position[1:]
        if mode == 1:
            point = (int(row_str)-1, cols.find(col_str.upper()))
        elif mode ==2:
            point = (int(row_str), cols.find(col_str.upper())+1)
        return (point)


    def cmd_and_resp(self,color,command):
        self.cmd_to_op(color,command)
        return self.get_resp(color)

    def initial_board(self,boardsize,komi): #初始化
        self.play_now=1
        self.is_pass=False
        self.who_wins=None
        commands=["boardsize "+str(boardsize),"komi "+str(komi),"clear_board"]
        for i in commands:
            self.cmd_and_resp(1,i)
            self.cmd_and_resp(-1,i)

    def get_score(self):
        command="final_score"
        score_b=self.cmd_and_resp(1,command)
        score_w=self.cmd_and_resp(-1,command)
        return score_b

    def record_game(self,game,move_info):
        node = game.extend_main_sequence()
        node.set_move(move_info.colour, move_info.move)


    def set_sgf(self,game,key,value):
        node = game.get_root()
        node.set(key,value)


    def run(self,boardsize=19,komi=7.5,isPrintBoard=True,filePath=None):
        self.initial_board(boardsize,komi)
        if filePath:
            sgf_recorder=sgf.Sgf_game(size=boardsize)
        else:
            sgf_recorder=None
        if isPrintBoard:
            board=GoBoard()
            os.system('cls')
            board.printBoard()
            #time.sleep(.5)
        while True:
            if self.play_now==1:    #黑棋下
                move=self.get_move(self.play_now)
                '''
                #判断是不是双方都弃手
                if move.lower() != 'pass':
                    self.is_pass=False
                elif self.is_pass is True:
                    break
                else:
                    self.is_pass=True
                if move.lower() == 'resign':
                    self.who_wins=-self.play_now
                    break
                else:
                    self.inform(-self.play_now,move)
                '''
            elif self.play_now==-1: #白棋下
                move=self.get_move(self.play_now)
                '''
                if move.lower() != 'pass':
                    self.is_pass=False
                elif self.is_pass is True:
                    break
                else:
                    self.is_pass=True
                if move.lower() == 'resign':
                    self.who_wins=-self.play_now
                    break
                else:
                    self.inform(-self.play_now,move)
                '''
            else:
                None
            #判断是不是双方都弃手
            if move.lower() != 'pass':
                self.is_pass=False
            elif self.is_pass is True:
                if filePath:    #记录这一步
                    if move.lower() != 'pass':
                        point=self.gtp_position_to_coords(move)
                    else:
                        point=None
                    m_info=move_info(self.play_now,point)
                    self.record_game(sgf_recorder,m_info)
                break
            else:
                self.is_pass=True
            if move.lower() == 'resign':
                self.who_wins=-self.play_now
                break
            else:
                self.inform(-self.play_now,move)

            if filePath:
                if move.lower() != 'pass':
                    point=self.gtp_position_to_coords(move)
                else:
                    point=None
                m_info=move_info(self.play_now,point)
                self.record_game(sgf_recorder,m_info)
            if isPrintBoard:
                if move.lower() != 'pass':
                    #os.system('cls')
                    whosTurn=Player.black if self.play_now==1 else Player.white
                    move=self.gtp_position_to_coords(move)
                    board.envUpdate(whosTurn,move)
                    board.printBoard()
                    #time.sleep(.5)
            self.play_now=-self.play_now    #交换棋手
        if self.who_wins is not None:
            '''
            print('winner is :',self.who_wins)
            '''
            if filePath:
                if self.who_wins==1:
                    value='B+Resign'
                else:
                    value='W+Resign'
                self.set_sgf(sgf_recorder,'RE',value)
        else:
            scores=self.get_score()
            if filePath:
                self.set_sgf(sgf_recorder,'RE',scores)
            '''
            winner=re.match('\w*',scores).group().lower()
            score=float(re.search("\d+.*",scores).group())
            if winner == 'b' or winner == 'black':
                self.who_wins=1
            elif winner == 'w' or winner == 'white':
                self.who_wins=-1
            print('winner is :',self.who_wins)
            '''
        if filePath:
            with open(filePath, "wb") as f:
                f.write(sgf_recorder.serialise())


if __name__ == "__main__":
    ai='fuego'
    game = ai_vs_ai(ai_b=ai,ai_w=ai)
    file_path='./sgfs/'
    filename=ai+'_'
    since=time.time()
    for i in range(3000,3001):
        print(i)
        filePath=file_path+filename+str(i)+'.sgf'
        game.run(boardsize=9,filePath=filePath,isPrintBoard=False)
    print(time.time()-since)
